#pragma once
#include <iostream>
#include <queue>
#include <vector>
#include "Thread.hpp"
#include"Mutex.hpp"

const static int defaultnum = 5;

template <class T>
class ThreadPool
{
private:
    bool IsEmpty()
    {
        return _taskqueue.empty();
    }
    void Routine()
    {
        while(true)
        {
            {
                T t;
                LockGuard lockguard(&_lock);
                while(IsEmpty())
                {
                    _cond.Wait();
                }
                t=_taskqueue.front();
                _taskqueue.pop();
            }
        }
    }
public:
    ThreadPool(int threadnum = defaultnum)
        : _threadnum(threadnum)
    {
        for (int i = 0; i < _threadnum; i++)
        {
            std::string name = "Thread-" + std::to_string(i+1);
            _threads.emplace([this](){this->Routine()}, name);
        }
    }
    void Start()
    {
        for(auto&throud:_threads)
        {
            throud.Start();
        }
    }
    void Enqueue(const T &in)
    {
        {
            LockGuard lockguard(&_lock);
            _taskqueue.push(in);
        }
    }
    void Wait()
    {
        for(auto&throud:_threads)
        {
            throud.Join();
        }
    }
    void Stop()
    {
    }
    ~ThreadPool() {}

private:
    std::queue<T> _taskqueue;     // 任务队列
    std::vector<Thread> _threads; // 线程池
    int _threadnum;               // 线程池中的线程数量

    Mutex _lock;
    Cond _cond;
};